package com.cdxy.service.impl;

import com.cdxy.dmr.dataObject.SmsTemplateDO;
import com.cdxy.dmr.dataObject.SmsVerifyLogDO;
import com.cdxy.dmr.repository.SmsTemplateRepository;
import com.cdxy.dmr.repository.SmsVerifyLogRepository;
import com.cdxy.enums.BizErrorEnum;
import com.cdxy.enums.KaptchaEnum;
import com.cdxy.model.dto.base.exception.BusinessException;
import com.cdxy.model.dto.base.exception.enums.CommonErrorEnum;
import com.cdxy.service.ISmsService;
import com.cdxy.util.CommonUtil;
import com.cdxy.util.EnvironmentUtil;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;

/**
 * @Author: tangy
 * @Date: 2020/2/23 17:03
 */
@Service
public class SmsServiceImpl implements ISmsService {

    @Autowired
    private SmsTemplateRepository smsTemplateRepository;

    @Autowired
    private SmsVerifyLogRepository smsVerifyLogRepository;

    @Value("${tenxun.appid}")
    private Integer appid;

    @Value("${tenxun.appkey}")
    private String appkey;

    @Value("${tenxun.templateId}")
    private Integer templateId;

    @Value("${tenxun.smsSign}")
    private String smsSign;

    /**
     * 失效时间  单位：分钟
     */
    private String expireTime = "5";


    @Override
    public void sendSms(KaptchaEnum.BusinessCode businessCode, String phone) {
        if (!CommonUtil.checkPhone(phone)) {
            throw new BusinessException(CommonErrorEnum.PARAM_ERROR, "请输入正确的手机号");
        }

        // 根据场景查询数据库模板
        SmsTemplateDO smsTemplateDO = smsTemplateRepository.getOrderByWeightDesc();

        // 发送验证码
        String code = "666666";
        if (!EnvironmentUtil.isLoc()) {
            ArrayList list = new ArrayList(2);
            code = RandomStringUtils.randomNumeric(6);
            //验证码
            list.add(code);
            //过期时间
            list.add(expireTime);
            try {
                SmsSingleSender ssender = new SmsSingleSender(appid, appkey);
                SmsSingleSenderResult result = ssender.sendWithParam("86", phone, templateId, list, smsSign, "", "");
                // 签名参数未提供或者为空时，会使用默认签名发送短信
                System.out.println(result);
                if (result.result != 0) {
                    throw new BusinessException(BizErrorEnum.SEND_SMS_ERROR);
                }
            } catch (Exception e) {
                //  错误
                throw new BusinessException(BizErrorEnum.SEND_SMS_ERROR);
            }
        }

        // 保存数据库
        SmsVerifyLogDO smsVerifyLogDO = new SmsVerifyLogDO();
        smsVerifyLogDO.setBusinessType(KaptchaEnum.Type.SMS.name());
        smsVerifyLogDO.setCode(code);
        smsVerifyLogDO.setMobile(phone);
        smsVerifyLogDO.setScene(businessCode.name());
        smsVerifyLogRepository.save(smsVerifyLogDO);
    }

    @Override
    public void verifySms(KaptchaEnum.BusinessCode businessCode, String phone, String code) {
        // 数据库获取
        SmsVerifyLogDO smsVerifyLogDO = smsVerifyLogRepository.getByBusinessTypeAndSceneAndMobileOrderBySceneOrderByIdDesc(KaptchaEnum.Type.SMS.name(), businessCode, phone);
        if (smsVerifyLogDO == null || smsVerifyLogDO.getVerifyTime() != null) {
            throw new BusinessException(BizErrorEnum.VERIFICATION_CODE_ERROR, "请先获取验证码");
        }
        // 比对时间和正确性
        if (smsVerifyLogDO.getCreateTime().plusMinutes(Integer.parseInt(expireTime)).isBefore(LocalDateTime.now())) {
            throw new BusinessException(BizErrorEnum.VERIFICATION_CODE_TIMEOUT_ERROR);
        }
        if (!smsVerifyLogDO.getCode().equalsIgnoreCase(code)) {
            throw new BusinessException(BizErrorEnum.VERIFICATION_CODE_ERROR);
        }

        SmsVerifyLogDO smsVerifyLogUpdateDO = new SmsVerifyLogDO();
        smsVerifyLogUpdateDO.setId(smsVerifyLogDO.getId());
        smsVerifyLogUpdateDO.setVerifyTime(LocalDateTime.now());
        smsVerifyLogRepository.updateById(smsVerifyLogUpdateDO);
    }
}
